<template>
	<div class="ant-dropdown-menu s-tool-column ant-dropdown-content">
		<a-spin :spinning="spinning">
			<div class="s-tool-column-header s-tool-column-item">
				<a-checkbox :checked="checkAll" :indeterminate="indeterminate" @change="onCheckAllChange"> 列展示 </a-checkbox>
				<a @click="reset">重置</a>
				<a v-if="change" class="ml-2" @click="submit">提交</a>
			</div>
			<a-divider />
			<div class="ant-checkbox-group">
				<div>
					<draggable :list="columnsSetting" animation="300" item-key="dataIndex" @end="emitColumnChange">
						<template #item="{ element }">
							<div class="s-tool-column-item">
								<div class="s-tool-column-handle layout-items-center">
									<more-outlined />
									<more-outlined />
								</div>
								<a-checkbox v-model:checked="element.checked" @change="onChange">{{ element.title }} </a-checkbox>
							</div>
						</template>
					</draggable>
				</div>
			</div>
		</a-spin>
	</div>
</template>

<script>
	import draggable from 'vuedraggable-es'
	import userConfigApi from '@/api/sys/userConfigApi'

	export default {
		components: {
			draggable
		},
		props: {
			columns: {
				type: Array,
				default: () => []
			},
			tableId: String,
			idMap: {
				type: Map,
				default: () => new Map()
			}
		},
		data() {
			return {
				spinning: false,
				indeterminate: false,
				checkAll: true,
				change: false,
				columnsSetting: [],
				originColumns: []
			}
		},
		mounted() {
			this.columnsSetting = this.columns.map((value) => {
				if (value.checked == undefined) {
					return {
						...value,
						checked: true
					}
				} else return value
			})
			// 这里要用深的拷贝，否则，勾选了字段时会修改了originColumns里的内容
			this.originColumns = this.columnsSetting.map((value) => ({ ...value }))
			// 处理全选组件
			const checkedList = this.columnsSetting.filter((value) => value.checked)
			this.checkAll = checkedList.length == this.columnsSetting.length
			this.indeterminate = checkedList.length > 0 && !this.checkAll
			// 重置更改态
			this.change = false
		},
		methods: {
			// 提交列配置
			submit() {
				const param = []
				this.columnsSetting.forEach((e, index) => {
					const id = this.idMap.get(e.dataIndex) ?? 0
					param.push({
						id: id,
						tableId: this.tableId,
						columnId: e.dataIndex,
						isShow: e.checked,
						sort: index,
						width: 'auto'
					})
				})

				this.spinning = true
				userConfigApi
					.sysEditColumn(param)
					.then((res) => {
						this.change = false
					})
					.finally(() => {
						this.spinning = false
					})
			},
			reset() {
				this.columnsSetting = this.originColumns.map((value) => ({ ...value }))
				this.indeterminate = false
				const checkedList = this.columnsSetting.filter((value) => value.checked)
				this.checkAll = checkedList.length === this.columnsSetting.length
				this.emitColumnChange()
				this.change = false
			},
			onChange() {
				// 过滤出所有展示的列
				const checkedList = this.columnsSetting.filter((value) => value.checked)
				// 判断是否要设置中间状态
				this.indeterminate = Boolean(checkedList.length) && checkedList.length < this.columnsSetting.length
				// 判断是否要设置全选状态
				this.checkAll = checkedList.length === this.columnsSetting.length
				// 发送更改
				this.emitColumnChange()
				// 记录更改态
				this.change = true
			},
			onCheckAllChange(e) {
				e.preventDefault()
				const val = e.target.checked
				Object.assign(this, {
					indeterminate: false,
					checkAll: val,
					columnsSetting: this.columns.map((value) => ({
						...value,
						checked: val
					}))
				})
				this.emitColumnChange()
				// 记录更改态
				this.change = true
			},
			emitColumnChange() {
				// eslint-disable-next-line vue/require-explicit-emits
				this.$emit('columnChange', this.columnsSetting)
			}
		}
	}
</script>

<style lang="less" scoped></style>
